/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: DataBaseUtil
 * Author:   步步为莹
 * Date:     2019/8/18 15:27
 * Description: 对常见数据库操作的封装
 * History:
 */
package cn.beyond.vehicleManagement.util;

import cn.beyond.vehicleManagement.dao.BaseDao;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

/**
 * 〈对常见数据库操作的封装〉<br> 
 * 〈一句话功能简述〉
 *
 * @author 步步为莹
 * @create 2019/8/18
 * @since 1.0.0
 */
public   class DataBaseUtil<T>  extends BaseDao {
    //private static  final  BaseDao dao = new BaseDao();
    private BaseDao dao=new BaseDao();

    /**
     * 插入的通用方法
     * @param t
     * @return
     */
    public  int addUtil(T t,String tableName){
        //获得数据库列名集合
         String strvalues=GetDataColumn(t);
        //通过反射获得类的属性数组
        String  str=getObjectString(t,'a');
        //获取字段数拼接成问号格式
        String strQuestionMark=getQuestionMarkCount(t);
       String sql="insert into\t"+tableName+"\t("+strvalues+")\tvalues("+strQuestionMark+")";
       int count=-1;
        try{
            count=super.executeUpdate(sql,str.split(","));
        }catch (Exception e){
            e.printStackTrace();
            count=0;
        }
        return count;
    }

    /**
     * 删除通用方法(限单字段)
     * @param obj
     * @param tableName
     * @param column
     * @return
     */
    public int delByIdUtil( Object obj,String tableName,String column){
        String sql="delete from "+tableName+"\twhere\t"+column+"=?";
        int count=-1;
        try{
             count= dao.executeUpdate(sql,obj);
        }finally {
            dao.closeAll();
        }

        return  count;
    }

    /**
     * 更新通用方法(限单字段)
     * @param t
     * @param tableName
     * @return
     */
    public int updateByidUtil(T t,String tableName){
        //通过反射获得参数列表
        String  str=getObjectString(t,'u');
        //获取字段数拼接成问号格式
        String strQuestionMark=getUpdateString(t);
        String sql="update\t"+tableName+"\tset\t"+strQuestionMark;
        System.out.println(str+"\t");
        System.out.println(sql);
        int count=-1;
        try{
            count=super.executeUpdate(sql,str.split(","));
        }catch (Exception e){
            e.printStackTrace();
            count=0;
        }
        return count;
    }

    /**
     * 通用查询返回值为对象
     * @param <T>
     * @param t
     * @param tableName
     * @param selectmap
     * @return
     */

       public <T> T selectONE(T t, String tableName, Map<String, Object> selectmap){
           String str = getSelectSQL(t, selectmap);
           String sql=null;
           String strParams=null;
           ResultSet rs=null;
           if(str!=null){
               sql="select * from "+tableName+str.substring(0,str.indexOf(";"));
               strParams=str.substring(str.indexOf(";")+1);
               rs=super.executeQuery(sql,strParams.split(","));
           }else{
               sql="select * from "+tableName;
               rs=super.executeQuery(sql);
           }
           T t1=ResultUtil.resultToObject(rs,t);
           return  t1;
       }


    /**
     * 拼接通用查询sql
     * @param t
     * @param selectmap
     * @param <T>
     * @return
     */
    public  <T> String getSelectSQL(T t, Map<String, Object> selectmap) {
        Class cla=t.getClass();
        Field[]fields=cla.getDeclaredFields();
        StringBuilder sbQuestion=new StringBuilder();
        StringBuilder sb=new StringBuilder();
        String selectSql=null;
        sbQuestion.append("\twhere\t");
        if(selectmap.size()!=0){
            for(int i=0;i<fields.length;i++){
               // sbQuestion.append(fields[i].getName()+",");
            if(selectmap.containsKey(fields[i].getName())){
                sbQuestion.append(fields[i].getName());
                sbQuestion.append("=");
                sbQuestion.append("?\t");
                sbQuestion.append("and\t");
                sb.append(selectmap.get(fields[i].getName())+",");
               }
            }
             selectSql=sbQuestion.substring(0,sbQuestion.lastIndexOf("and")).toString()+";"
                    +sb.substring(0,sb.lastIndexOf(",")).toString();
        }

        return selectSql;
    }


    /**
     * 通用查询返回值为集合
     * @param <T>
     * @param t
     * @param tableName
     * @param selectmap
     * @return
     */
    public <T> List<T> selectAll(T t, String tableName, Map<String, Object> selectmap){
        String str = getSelectSQL(t, selectmap);
        String sql=null;
        String strParams=null;
        ResultSet rs=null;
        if(str!=null){
            sql="select * from "+tableName+str.substring(0,str.indexOf(";"));
            strParams=str.substring(str.indexOf(";")+1);
            rs=super.executeQuery(sql,strParams.split(","));
        }else{
            sql="select * from "+tableName;
            rs=super.executeQuery(sql);
        }
        System.out.println(sql);
        List<T>list=ResultUtil.resultToList(rs,t);
        return  list;
    }

    /**
     *  使用将对象的值通过get方法获得并拼接成字符串
     * @param t
     * @return
     */
    public   String getObjectString(T t,char type){
        //获得反射类
        Class cla=t.getClass();
        //定义stringbulider拼接字符串
        StringBuilder sb=new StringBuilder();
        Object first=null;
        //获得字段数组
        Field[] fields=cla.getDeclaredFields();
        for (int i=0;i<fields.length;i++){

            PropertyDescriptor pd=null;
            try{
                //反射属性描述器
                pd=new PropertyDescriptor(fields[i].getName(),cla);
                //获得反射的get方法
             Method method= pd.getReadMethod();
             //获得对象指定属性的值
             Object o=method.invoke(t);
             if(i==0){
                 first=o;
             }
             sb.append(o);
             sb.append(",");
            } catch (IntrospectionException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

        String str = sb.toString();
        //判断类型为添加或更新
        if(type=='a'){
        str=str.substring(str.indexOf(",")+1,str.lastIndexOf(","));
        }else if(type=='u'){
            str=str.substring(str.indexOf(",")+1)+first;
        }
        return  str;
    }

    /**
     * 拼接问号字符串
     * @param t
     * @return
     */
    public String getQuestionMarkCount(T t){
        //获得类的属性个数
        int count=t.getClass().getDeclaredFields().length-1;
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<count;i++){
            sb.append("?");
            sb.append(",");
        }
        String str=sb.toString();
        return str.substring(0,str.lastIndexOf(","));
    }

    /**
     * 拼接更新字符串问号
     * @param t
     * @return
     */
    public  String getUpdateString(T t){
        //获得反射类
        Class cla=t.getClass();
        //定义stringbulider拼接字符串
        StringBuilder sb=new StringBuilder();
        String first=null;
        //获得字段数组
        Field[]fields=cla.getDeclaredFields();
        for (int i=0;i<fields.length;i++){
            sb.append(fields[i].getName());
            sb.append("=?,");
            if(i==0){
                first=fields[i].getName();
            }
        }
        String updateStr=sb.toString();
        return  updateStr.substring(updateStr.indexOf(",")+1,updateStr.lastIndexOf(","))
                +"\twhere\t"+first+"=?";
    }

    /**
     * 获取查询value前的拼接字符串，id不传入参数
     * @param t
     * @return
     */
    public String GetDataColumn(T t){
        Class cla=t.getClass();
        Field[]fields=cla.getDeclaredFields();
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<fields.length;i++){
            sb.append(fields[i].getName());
            sb.append(",");
        }
        String str1= sb.toString();
        return str1.substring(str1.indexOf(",")+1,str1.lastIndexOf(",")) ;
    }
}